// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.webviewflutter;

import static androidx.core.app.ActivityCompat.startActivityForResult;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Message;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.view.WindowManager;


import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import androidx.core.content.FileProvider;
import androidx.loader.content.CursorLoader;

import com.luck.picture.lib.basic.PictureSelector;
import com.luck.picture.lib.config.SelectMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.interfaces.OnResultCallbackListener;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.WebChromeClientHostApi;

/**
 * Host api implementation for {@link WebChromeClient}.
 *
 * <p>Handles creating {@link WebChromeClient}s that intercommunicate with a paired Dart object.
 */
public class WebChromeClientHostApiImpl implements WebChromeClientHostApi {
  private final InstanceManager instanceManager;
  private final WebChromeClientCreator webChromeClientCreator;
  private final WebChromeClientFlutterApiImpl flutterApi;
  static ValueCallback<Uri[]> mUploadCallBackAboveL;
  static FrameLayout videoFrame;
  static WebChromeClient.CustomViewCallback vedioCallBack;

  /**
   * Implementation of {@link WebChromeClient} that passes arguments of callback methods to Dart.
   */
  public static class WebChromeClientImpl extends WebChromeClient implements Releasable {
    @Nullable private WebChromeClientFlutterApiImpl flutterApi;
    private WebViewClient webViewClient;

    /**
     * Creates a {@link WebChromeClient} that passes arguments of callbacks methods to Dart.
     *
     * @param flutterApi handles sending messages to Dart
     * @param webViewClient receives forwarded calls from {@link WebChromeClient#onCreateWindow}
     */
    public WebChromeClientImpl(
        @NonNull WebChromeClientFlutterApiImpl flutterApi, WebViewClient webViewClient) {
      this.flutterApi = flutterApi;
      this.webViewClient = webViewClient;
    }

    @Override
    public boolean onCreateWindow(
        final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
      return onCreateWindow(view, resultMsg, new WebView(view.getContext()));
    }

    /**
     * Verifies that a url opened by `Window.open` has a secure url.
     *
     * @param view the WebView from which the request for a new window originated.
     * @param resultMsg the message to send when once a new WebView has been created. resultMsg.obj
     *     is a {@link WebView.WebViewTransport} object. This should be used to transport the new
     *     WebView, by calling WebView.WebViewTransport.setWebView(WebView)
     * @param onCreateWindowWebView the temporary WebView used to verify the url is secure
     * @return this method should return true if the host application will create a new window, in
     *     which case resultMsg should be sent to its target. Otherwise, this method should return
     *     false. Returning false from this method but also sending resultMsg will result in
     *     undefined behavior
     */
    @VisibleForTesting
    boolean onCreateWindow(
        final WebView view, Message resultMsg, @Nullable WebView onCreateWindowWebView) {
      final WebViewClient windowWebViewClient =
          new WebViewClient() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public boolean shouldOverrideUrlLoading(
                @NonNull WebView windowWebView, @NonNull WebResourceRequest request) {
              if (!webViewClient.shouldOverrideUrlLoading(view, request)) {
                view.loadUrl(request.getUrl().toString());
              }
              return true;
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView windowWebView, String url) {
              if (!webViewClient.shouldOverrideUrlLoading(view, url)) {
                view.loadUrl(url);
              }
              return true;
            }
          };

      if (onCreateWindowWebView == null) {
        onCreateWindowWebView = new WebView(view.getContext());
      }
      onCreateWindowWebView.setWebViewClient(windowWebViewClient);

      final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
      transport.setWebView(onCreateWindowWebView);
      resultMsg.sendToTarget();

      return true;
    }

      @RequiresApi(api = Build.VERSION_CODES.M)
      private void initLayout(WebView view){
          // 创建FrameLayout并设置布局参数
          FrameLayout frameLayout = new FrameLayout(view.getContext());

          // 获取DisplayMetrics对象
          WindowManager windowManager = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
          DisplayMetrics dm = new DisplayMetrics();//屏幕度量
          windowManager.getDefaultDisplay().getMetrics(dm);
          int screenWidthPixels = dm.widthPixels;//宽度
          int screenHeightPixels = dm.heightPixels ;//高度


          // 如果你想将屏幕宽度转换为dp（密度独立像素），可以使用以下代码：
          FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(screenWidthPixels,screenHeightPixels);
          frameLayout.setLayoutParams(layoutParams);
          // 设置FrameLayout的背景颜色（可选）
          frameLayout.setBackgroundColor(Color.GRAY); // 设置背景颜色
          // 在FrameLayout中添加其他视图（可选）
          // 例如，添加一个按钮到FrameLayout中心位置
//          Button button = new Button(view.getContext());
//          button.setText("Click me");
//          FrameLayout.LayoutParams buttonParams = new FrameLayout.LayoutParams(
//                  FrameLayout.LayoutParams.WRAP_CONTENT,
//                  FrameLayout.LayoutParams.WRAP_CONTENT,
//                  Gravity.CENTER
//          );
//          button.setLayoutParams(buttonParams);
//          button.setOnClickListener(new View.OnClickListener() {
//              @Override
//              public void onClick(View v) {
//                  videoFrame.setVisibility(View.GONE);
//                  videoFrame.removeAllViews();
//              }
//          });
//          frameLayout.addView(button);
          videoFrame = frameLayout;
          videoFrame.setVisibility(View.GONE);
          view.addView(videoFrame);
      }


      @Override
      public void onShowCustomView(View view, CustomViewCallback callback) {
          super.onShowCustomView(view, callback);
          Log.d("kkkkkkkkkk","88888888");
          FrameLayout.LayoutParams buttonParams = new FrameLayout.LayoutParams(
                  FrameLayout.LayoutParams.WRAP_CONTENT,
                  FrameLayout.LayoutParams.WRAP_CONTENT,
                  Gravity.CENTER
          );
          view.setLayoutParams(buttonParams);
          videoFrame.removeAllViews();
          videoFrame.setVisibility(View.VISIBLE);
          videoFrame.addView(view);
          vedioCallBack = callback;

      }

      @Override
      public void onHideCustomView() {
          Log.d("kkkkkkkkkk","777777");
          super.onHideCustomView();
          videoFrame.setVisibility(View.GONE);
          videoFrame.removeAllViews();
          vedioCallBack.onCustomViewHidden();
      }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onProgressChanged(WebView view, int progress) {
      if (flutterApi != null) {
        flutterApi.onProgressChanged(this, view, (long) progress, reply -> {});
      }
        if (progress > 0 && videoFrame == null){
            initLayout(view);
        }
    }

    /**
     * Set the {@link WebViewClient} that calls to {@link WebChromeClient#onCreateWindow} are passed
     * to.
     *
     * @param webViewClient the forwarding {@link WebViewClient}
     */
    public void setWebViewClient(WebViewClient webViewClient) {
      this.webViewClient = webViewClient;
    }

    @Override
    public void release() {
      if (flutterApi != null) {
        flutterApi.dispose(this, reply -> {});
      }
      flutterApi = null;
    }

//    // For Android 3.0-
//    public void openFileChooser(ValueCallback<Uri> valueCallback) {
//      Log.d("=ΩΩΩΩΩΩ====LLLLLLLLL", "=======>>>>>>>>>>><<<<<<<<<<<<<<<<<<1");
//      mUploadCallBack = valueCallback;
//      showFileChooser();
//    }
//
    // For Android 3.0+
    public void openFileChooser(ValueCallback valueCallback, String acceptType) {
      Log.d("kkkkkkkkkk", "=======>>>>>>>>>>><<<<<<<<<<<<<<<<<<2");
//      mUploadCallBack = valueCallback;
//      showFileChooser();
    }

    //For Android 4.1
    public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
      Log.d("kkkkkkkkkk", "=======>>>>>>>>>>><<<<<<<<<<<<<<<<<<3");
//      mUploadCallBack = valueCallback;
//      showFileChooser();
    }

    // For Android 5.0+
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
      Log.d("kkkkkkkkkk", "onFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
      boolean allowMultiple = fileChooserParams.getMode() == FileChooserParams.MODE_OPEN_MULTIPLE;//是否多选
      mUploadCallBackAboveL = filePathCallback;
      int chooseMode ;
      String[] array = fileChooserParams.getAcceptTypes();
      List<String> list = Arrays.asList(array);
      if (list.contains("video/*")) {
        chooseMode = SelectMimeType.ofVideo();
      } else {
        chooseMode = SelectMimeType.ofImage();
      }
      showFileChooser(webView.getContext(),allowMultiple,chooseMode);
      return true;
    }



    /**
     * 打开选择图片/相机
     */
    private void showFileChooser(Context context, boolean allowMultiple,int chooseMode) {
//        Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
////        intent.setAction("com.example.MY_ACTION");
////        intent.putExtra("key", "value");
//        context.startActivity(intent);
//        mUploadCallBackAboveL.onReceiveValue(null);
//
//        return;
      PictureSelector.create(context)
              .openGallery(chooseMode)
              .setImageEngine(GlideEngine.createGlideEngine())
              .setMaxSelectNum(allowMultiple?20:1)
              .forResult(new OnResultCallbackListener<LocalMedia>() {
                @Override
                public void onResult(ArrayList<LocalMedia> result) {
                    String androidVersion = android.os.Build.VERSION.RELEASE;
                    String model = Build.MODEL;
                    String manufacturer = Build.MANUFACTURER;
                    Log.d("kkkkkk",androidVersion);
                    Log.d("kkkkkk",model);
                    Log.d("kkkkkk",manufacturer);

                  ArrayList<Uri>list = new ArrayList<>();
                  if (mUploadCallBackAboveL != null) {
                    for (LocalMedia e:result) {
//                        e.getRealPath()
                        if (androidVersion.equals("9") && manufacturer.equals("HUAWEI")) {
                            list.add(Uri.fromFile(new File(e.getPath())));
                        }else{
                            list.add(Uri.parse(e.getPath())); //此方法在华为中端机上无响应
                        }
//                        Uri u1 = Uri.parse(e.getPath());
//                        Log.d("kkkkkk",u1.getPath());
//                        Uri u2 = Uri.fromFile(new File(e.getPath()));
//                        Log.d("kkkkkk2",u2.getPath());
//                        Log.e("kkkkkk33",getRealPathFromURI(context, u2));
//                        list.add(Uri.parse(getRealPathFromURI(context, u2)));
                    }
                    Uri[] a = list.toArray(new Uri[0]);
                    mUploadCallBackAboveL.onReceiveValue(list.toArray(new Uri[0]));


                  }
                }

                @Override
                public void onCancel() {
                  mUploadCallBackAboveL.onReceiveValue(null);
                }
              });
    }

      private String getRealPathFromURI(Context context,  Uri contentUri) { //传入图片uri地址
          String[] projection = { MediaStore.Images.ImageColumns.DATA };
          Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
          Cursor cursor = null;
          try {
              cursor = context.getContentResolver().query(uri, projection, null, null, MediaStore.Images.Media.DATE_ADDED + " DESC");
              if (cursor != null && cursor.moveToFirst()) {
                  String imagePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
                  // 这里imagePath就是设备上相册的真实路径
                  return imagePath;
              }
          } finally {
              if (cursor != null) {
                  cursor.close();
              }
          }

          return null;
      }
  }

  /** Handles creating {@link WebChromeClient}s for a {@link WebChromeClientHostApiImpl}. */
  public static class WebChromeClientCreator {
    /**
     * Creates a {@link DownloadListenerHostApiImpl.DownloadListenerImpl}.
     *
     * @param flutterApi handles sending messages to Dart
     * @param webViewClient receives forwarded calls from {@link WebChromeClient#onCreateWindow}
     * @return the created {@link DownloadListenerHostApiImpl.DownloadListenerImpl}
     */
    public WebChromeClientImpl createWebChromeClient(
        WebChromeClientFlutterApiImpl flutterApi, WebViewClient webViewClient) {
      return new WebChromeClientImpl(flutterApi, webViewClient);
    }
  }

  /**
   * Creates a host API that handles creating {@link WebChromeClient}s.
   *
   * @param instanceManager maintains instances stored to communicate with Dart objects
   * @param webChromeClientCreator handles creating {@link WebChromeClient}s
   * @param flutterApi handles sending messages to Dart
   */
  public WebChromeClientHostApiImpl(
      InstanceManager instanceManager,
      WebChromeClientCreator webChromeClientCreator,
      WebChromeClientFlutterApiImpl flutterApi) {
    this.instanceManager = instanceManager;
    this.webChromeClientCreator = webChromeClientCreator;
    this.flutterApi = flutterApi;
  }

  @Override
  public void create(Long instanceId, Long webViewClientInstanceId) {
    final WebViewClient webViewClient =
        (WebViewClient) instanceManager.getInstance(webViewClientInstanceId);
    final WebChromeClient webChromeClient =
        webChromeClientCreator.createWebChromeClient(flutterApi, webViewClient);
    instanceManager.addInstance(webChromeClient, instanceId);
  }
}



class PickerPhoto extends Activity{
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK && data != null) {
            Uri selectedUri = data.getData();
            // 处理用户选择的联系人信息
        }
    }
}